/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.irssproject.app.service.recommendations.common;

import com.google.common.collect.Maps;
import com.irssproject.app.entitats.Reading;
import com.irssproject.app.service.recommendations.impl.RecommendationsServiceImpl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.htmlparser.jericho.Config;
import net.htmlparser.jericho.LoggerProvider;
import net.htmlparser.jericho.Source;
import net.sf.extjwnl.JWNLException;
import org.carrot2.clustering.lingo.LingoClusteringAlgorithm;
import org.carrot2.core.*;
import org.carrot2.core.attribute.CommonAttributesDescriptor;

/**
 *
 * @author adria
 */
@SuppressWarnings("unchecked")
public class RecommendationsCommon {

    static final Logger logger = Logger.getLogger(RecommendationsServiceImpl.class.getName());
    private static Controller controller;
    private static double TWB = 1;
    private final static int MIN_TWB = 2;
    private final static int MAX_TWB = 6;
    private final static double FACTOR_TWB = -0.01;
    private final static int charsPerWord = 6;

    public RecommendationsCommon() throws JWNLException, IOException {
    }

    static {
        logger.log(Level.INFO, "ControllerFactory creating controller with caching and pooling");
        controller = ControllerFactory.createCachingPooling(IDocumentSource.class);
    }

    public static ArrayList<Document> formatItemsToDocuments(List<Reading> lectures) {

        final String[][] data = new String[lectures.size()][3];

        long wordCount = 0;
        int i = 0;
        Source source;

        Config.LoggerProvider = LoggerProvider.DISABLED;
        if (lectures.isEmpty())
            i = 1;
        else 
            for (Reading lectura : lectures) {

                data[i][0] = lectura.getItem().getTitle();
                data[i][1] = lectura.getItem().getLink();
                //sum number of words of each item
                wordCount += lectura.getItem().getContent().length();
                source = new Source(lectura.getItem().getContent());
                data[i][2] = "" + source.getTextExtractor().setIncludeAttributes(true).toString();
                i++;
            }




        double avgWords = (wordCount / charsPerWord) / i;

        //Function: TWB = -x/100 + 6
        //add 1 to increment twb a little more
        TWB = (FACTOR_TWB * avgWords) + 6 + 1;

        if (TWB > MAX_TWB) {
            TWB = MAX_TWB;
        } else if (TWB < MIN_TWB) {
            TWB = MIN_TWB;
        }

        ArrayList<Document> documents = new ArrayList<Document>();
        for (String[] row : data) {
            documents.add(new Document(row[0], row[2], row[1]));
        }
//        logger.log(Level.INFO, "time for format documents: {0} ms", Calendar.getInstance().getTimeInMillis()-ini);

        return documents;

    }

    public static ProcessingResult lingoClustering(List<Reading> lectures, int clusterCountBase) throws Exception {

        List<Document> docs = formatItemsToDocuments(lectures);
        List<Document> documents = Collections.unmodifiableList(docs);
        final Map<String, Object> attributes = Maps.newHashMap();
        CommonAttributesDescriptor.attributeBuilder(attributes).documents(documents);
        attributes.put("LingoClusteringAlgorithm.desiredClusterCountBase", 100);
        attributes.put("LingoClusteringAlgorithm.titleWordsBoost", TWB);
        attributes.put("LingoClusteringAlgorithm.maximumMatrixSize", Integer.MAX_VALUE);
        attributes.put("LingoClusteringAlgorithm.dfThreshold", (Integer)(documents.size()/15));


        Map<String, Object> map = controller.process(attributes, LingoClusteringAlgorithm.class).getAttributes();        
        return controller.process(attributes, LingoClusteringAlgorithm.class);
    }
}
